﻿/* Copyright (c) 2010 EPiServer AB
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
using System;
using System.Text;
using System.Web.Security;
using EPiServer.Configuration;
using EPiServer.Core;
using EPiServer.Core.Html;
using EPiServer.DataAbstraction;
using EPiServer.Filters;
using EPiServer.Municipality.Configuration;
using EPiServer.Municipality.Web.Mail;
using EPiServer.PlugIn;

namespace EPiServer.Municipality.Web.Schedulers {
    /// <summary>
    /// Summary description for NewPageNotifierJob.
    /// </summary>
    /// <remarks>
    /// </remarks>
    [ScheduledPlugIn(LanguagePath = "/municipality/schedulers/newpagenotifier")]
    public class NewPageNotifierJob {
        /* *******************************************************************
        *  Properties 
        * *******************************************************************/
        #region protected static SiteSettings Config
        /// <summary>
        /// Gets the Config of the NewPageNotifierJob
        /// </summary>
        /// <value></value>
        protected static SiteSettings Config {
            get {
                if (_config == null) {
                    _config = new SiteSettings();
                    PlugInSettings.AutoPopulate(_config);
                }
                return _config;
            }
        }
        private static SiteSettings _config;
        #endregion
        #region private static ScheduledJob ThisJob
        /// <summary>
        /// Gets the ThisJob of the NewPageNotifierJob
        /// </summary>
        /// <value></value>
        private static ScheduledJob ThisJob {
            get {
                return ScheduledJob.Load("Execute", "EPiServer.Municipality.Web.Schedulers.NewPageNotifierJob", "EPiServer.Municipality");
            }
        }
        #endregion
        #region private static PageReference RootPages
        /// <summary>
        /// Gets the RootPages of the NewPageNotifierJob
        /// </summary>
        /// <value></value>
        private static PageReferenceCollection RootPages {
            get {
                var value = Config.RootPages;
                var rootPages = new PageReferenceCollection();
                if (!string.IsNullOrEmpty(value)) {
                    var values = value.Split(new[] { ',' });
                    if (values.Length > 0) {
                        foreach (var s in values) {
                            rootPages.Add(new PageReference((int.Parse(s))));
                        }
                    }
                    return rootPages;
                }
                rootPages.Add(PageReference.StartPage);
                return rootPages;
            }
        }
        #endregion
        #region private static string Sender
        /// <summary>
        /// Gets the Sender of the NewPageNotifierJob
        /// </summary>
        /// <value></value>
        private static string Sender {
            get {
                var sender = Config.Sender;
                if (string.IsNullOrEmpty(sender) || sender.IndexOf("@") <= 0) {
                    return Config.SystemEmail; 
                }
                return sender;
            }
        }
        #endregion
        #region private static string Receiver
        /// <summary>
        /// Gets the receiver of the NewPageNotifierJob
        /// </summary>
        /// <value></value>
        private static string Receiver {
            get {
                var receiver = Config.Receiver;
                if (string.IsNullOrEmpty(receiver) || receiver.IndexOf("@") <= 0) {
                    return Config.WebmasterEmail;
                }
                return receiver;
            }
        }
        #endregion
        #region private static TimeSpan NewPagesSince
        /// <summary>
        /// Gets the NewPagesSince of the NewPageNotifierJob
        /// </summary>
        /// <value></value>
        private static TimeSpan NewPagesSince {
            get {
                var job = ThisJob;
                if (job != null) {
                    if (job.IntervalType == ScheduledIntervalType.Seconds)
                        return TimeSpan.FromSeconds(job.IntervalLength);
                    if (job.IntervalType == ScheduledIntervalType.Minutes)
                        return TimeSpan.FromMinutes(job.IntervalLength);
                    if (job.IntervalType == ScheduledIntervalType.Hours)
                        return TimeSpan.FromHours(job.IntervalLength);
                    if (job.IntervalType == ScheduledIntervalType.Days)
                        return TimeSpan.FromDays(job.IntervalLength);
                    if (job.IntervalType == ScheduledIntervalType.Months)
                        return new TimeSpan(DateTime.Now.Ticks - DateTime.Now.AddMonths(-job.IntervalLength).Ticks);
                }
                return TimeSpan.FromDays(7);
            }
        }
        #endregion
        #region private static string Language
        /// <summary>
        /// Gets the Language of the NewPageNotifierJob
        /// </summary>
        /// <value></value>
        private static string Language {
            get {
                var language = Config.LanguageId;
                return !string.IsNullOrEmpty(language) ? language : "sv";
            }
        }
        #endregion
        /* *******************************************************************
        *  Static methods 
        * *******************************************************************/
        #region public static string Execute()
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static string Execute() {
            try {
                var propertyCriteriaCollection = new PropertyCriteriaCollection();
                var dateTime = DateTime.Today;

                var propertyCriteria = new PropertyCriteria
                                           {
                                               Name = "PageStartPublish",
                                               Value = dateTime.Subtract(NewPagesSince).ToString(),
                                               Condition = CompareCondition.GreaterThan,
                                               Type = PropertyDataType.Date,
                                               Required = false
                                           };
                propertyCriteriaCollection.Add(propertyCriteria);

                propertyCriteria = new PropertyCriteria
                                       {
                                           Name = "PageSaved",
                                           Value = dateTime.Subtract(NewPagesSince).ToString(),
                                           Condition = CompareCondition.GreaterThan,
                                           Type = PropertyDataType.Date,
                                           Required = false
                                       };
                propertyCriteriaCollection.Add(propertyCriteria);

                var collNewPages = new PageDataCollection();

                var languages = LanguageBranch.ListEnabled();

                foreach (var branch in languages) {
                    var lang = new LanguageSelector(branch.LanguageID);
                    foreach (var rootReference in RootPages) {
                        var langPages = DataFactory.Instance.FindPagesWithCriteria(rootReference, propertyCriteriaCollection, branch.LanguageID, lang);
                        collNewPages.Add(langPages);
                    }
                }
                
                if (collNewPages.Count > 0) {
                    Send(collNewPages);
                    return "[OK] " + String.Format(LanguageManager.Instance.Translate("/municipality/schedulers/newpagenotifier/returnstring", Language), collNewPages.Count, Receiver);
                }
                return "[OK] " + String.Format(LanguageManager.Instance.Translate("/municipality/schedulers/newpagenotifier/returnstringempty", Language), collNewPages.Count);
            } catch (Exception ex) {
                return "[FAILED] " + ex.Message;
            }
        }
        #endregion
        #region private static void Send(PageDataCollection newPages)
        /// <summary>
        /// The actual method called to send message
        /// </summary>
        /// <param name="newPages"></param>
        private static void Send(PageDataCollection newPages) {

            SortByLatestDate(newPages);

            string subject = String.Format(LanguageManager.Instance.Translate("/municipality/schedulers/newpagenotifier/subject", Language), Settings.Instance.SiteDisplayName);
            string introduction = string.Format(LanguageManager.Instance.Translate("/municipality/schedulers/newpagenotifier/introduction", Language), Settings.Instance.SiteDisplayName, NewPagesSince.Days);

            var builder = new StringBuilder();

            builder.Append("<p class=\"introduction\">");
            builder.Append(introduction);
            builder.Append("</p>");
            
            builder.Append("<ul>");
            foreach (PageData newPage in newPages) {
                builder.Append("<li>");

                builder.Append("<a href=\"");
                builder.Append(MailUtil.GeneratePageUrl(newPage));
                builder.Append("\">");
                builder.Append(newPage.PageName);
                builder.Append("</a>");
                builder.Append("<br />");

                //Date and user that saved the page 
                builder.Append("<span class=\"date\">");
                builder.Append(LanguageManager.Instance.Translate("/municipality/schedulers/newpagenotifier/createdby", Language));
                MembershipUser user = Membership.GetUser(newPage.ChangedBy);
                if (user != null) {
                    builder.Append(user.UserName + " ");
                } else {
                    builder.Append(newPage.ChangedBy + " ");
                }
                builder.Append(((DateTime)newPage["PageSaved"]).ToShortDateString());
                builder.Append("</span>");
                builder.Append("<br />");

                //Introduction text
                string pageBody = null;
                if (newPage["MainIntro"] != null) {
                    pageBody = newPage.Property["MainIntro"].ToWebString();
                } else {
                    var strippedBody = TextIndexer.StripHtml(newPage["MainBody"] as string, 255);
                    if (strippedBody != null) {
                        pageBody = strippedBody;
                    }
                }
                if(!string.IsNullOrEmpty(pageBody)) {
                    builder.Append(pageBody);
                    builder.Append("<br />");
                }

                //Editlink
                builder.Append("<a class=\"textlink\" href=\"");
                builder.Append(UriSupport.UIUrl + "edit/default.aspx?id=" + newPage.PageLink.ID);
                builder.Append("\">");
                builder.Append(LanguageManager.Instance.Translate("/municipality/misc/editpage", Language));
                builder.Append("</a>");
                builder.Append("<br />");
                builder.Append("<br />");

                builder.Append("</li>");
            }
            builder.Append("</ul>");

            MailUtil.SendHtmlMail(subject, builder.ToString(), Receiver, Sender);
        }
        #endregion
        #region private static void SortByLatestDate(PageDataCollection pages)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pages"></param>
        private static void SortByLatestDate(PageDataCollection pages) {
            var filter = new FilterSort(FilterSortOrder.CreatedDescending);
            filter.Filter(null, new FilterEventArgs(pages));
        }
        #endregion
    }
}